<?php

namespace Trois\WorkWechat;

use EasySwoole\EasySwoole\Logger;
use Trois\Lib\Help;

class WechatClient
{
    // 获取 token
    private string $get_token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken';

    //通讯录管理
    // 获取企业微信部门列表
    private string $department_list_url = 'https://qyapi.weixin.qq.com/cgi-bin/department/list';
    // 根据成员批量获取客户详情
    private string $client_user_all_info_url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user';

    //客户联系「联系我」管理
    private string $add_contact_way = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way';
    private string $update_contact_way = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way';
    //获取配置了客户联系功能的成员列表
    private string $get_follow_user_list = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list';

    private array $wxk_info; //企业配置信息

    private array $error_info = [
        41054 => '该用户尚未激活',
        40098 => '成员尚未实名认证',
        60111 => '账号不属于该主体,请核实',
    ];

    private string $error = "";

    private string $type = "";

    private array $success;

    private string $work_wechat_access_token = 'work_wechat_access_token:';

    public function __construct(array $workWechatConfig, string $type = 'wxk_customer_admin_secret')
    {
        $this->wxk_info = $workWechatConfig;
        $this->type = $type;
    }

    public function setError(string $error): void
    {
        $this->error = $error;
    }

    public function setSuccess(array $success): void
    {
        $this->success = $success;
    }

    public function getError(): string
    {
        return $this->error;
    }

    public function getSuccess(): array
    {
        return $this->success;
    }

    protected array $access_token;

    /**
     * 根据不同业务获取不同 access_token
     * $type: wxk_customer_admin_secret 客户的, wxk_address_book_secret 员工的
     * $type 已作废，已调整到构造方法上
     */
    public function get_access_token(string $type = ''): string
    {
        $key = $this->work_wechat_access_token . $this->type . ':' . $this->wxk_info['corpid'];

        if (isset($this->access_token[$key])) {
            return $this->access_token[$key];
        }

        $access_token = Help::redisPoolStringInvoke($key);

        if ($access_token) {
            $this->access_token[$key] = $access_token;
            return $access_token;
        }

        $res = Help::curl('post', $this->get_token_url, json_encode([
            'corpid' => $this->wxk_info['corpid'],
            'corpsecret' => $this->wxk_info[$this->type]
        ]));

        if ($res['response_code'] !== 0) {
            self::setError($res['response_message']);
            return '';
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = 'WechatClient 获取ACCESS_TOKEN失败！MESSAGE：' . $result['errmsg'] . ', CODE:' . $result['errcode'];
            self::setError($error);
            return '';
        }

        Help::redisPoolStringInvoke($key, $result['access_token'], ($result['expires_in'] - 100));

        return $result['access_token'];

    }

    /**
     * 删除accesstoken缓存，用于刷新Token
     * @param string $type
     * @return void
     */
    public function remove_access_token(string $type): void
    {
        $key = $this->work_wechat_access_token . $type . ':' . $this->wxk_info['corpid'];
        Help::redisPoolStringDelInvoke($key);
    }

    /**
     * 配置客户联系「联系我」方式
     * 参考文档：https://developer.work.weixin.qq.com/document/path/92228
     * 注意事项：当type=2时，user参数不能为空
     */
    public function add_contact_way(array $param, array $wechat = []): bool
    {

        $access_token = $this->get_access_token();

        if (!$access_token) {
            return false;
        }

        $res = Help::curl('post', $this->add_contact_way . '?access_token=' . $access_token, json_encode($param));

        if ($res['response_code'] !== 0) {
            $error = '配置客户联系「联系我」方式失败！MESSAGE1：' . $res['response_message'] . ', PARAM:' . json_encode($param) . ', wechat:' . json_encode($wechat, JSON_UNESCAPED_UNICODE) . ', type:' . $this->type . ', wxk_info:' . json_encode($this->wxk_info, JSON_UNESCAPED_UNICODE);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '配置客户联系「联系我」方式失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', PARAM:' . json_encode($param) . ', wechat:' . json_encode($wechat, JSON_UNESCAPED_UNICODE) . ', type:' . $this->type . ', wxk_info:' . json_encode($this->wxk_info, JSON_UNESCAPED_UNICODE);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $this->setSuccess($result);

        return true;

    }

    /**
     * 获取客户详情
     * https://work.weixin.qq.com/api/doc/90001/90143/92265
     */
    public function externalcontact_get(string $external_userid, array $decryptMsg, bool $all = false): array
    {

        $access_token = $this->get_access_token();

        if (!$access_token) {
            return [];
        }

//        $url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=" . $access_token . '&debug=1&external_userid=' . $external_userid;
        $url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=" . $access_token . '&external_userid=' . $external_userid;

        $res = Help::curl('get', $url);

        if ($res['response_code'] !== 0) {
            $error = '获取客户详情失败！MESSAGE1：' . $res['response_message'] . ', decryptMsg:' . json_encode($decryptMsg, JSON_UNESCAPED_UNICODE);
            Logger::getInstance()->error($error);
            self::setError($error);
            return [];
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '获取客户详情失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', decryptMsg:' . json_encode($decryptMsg, JSON_UNESCAPED_UNICODE);
            Logger::getInstance()->error($error);
            self::setError($error);
            return [];
        }


        return $all ? $result : $result['external_contact'];
    }

    /**
     * 外部联系人openid转换
     * 来源：https://work.weixin.qq.com/api/doc/90001/90143/92292
     */
    public function convert_to_openid(string $external_userid, array $decryptMsg): string
    {

        $access_token = $this->get_access_token();

        if (!$access_token) {
            return '';
        }

        $url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/convert_to_openid?access_token=' . $access_token;

        $res = Help::curl('post', $url, json_encode([
            'external_userid' => $external_userid,
        ]));

        if ($res['response_code'] !== 0) {
            $error = '外部联系人openid转换失败！MESSAGE1：' . $res['response_message'] . ', decryptMsg:' . json_encode($decryptMsg, JSON_UNESCAPED_UNICODE);
            Logger::getInstance()->error($error);
            self::setError($error);
            return '';
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '外部联系人openid转换失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', decryptMsg:' . json_encode($decryptMsg, JSON_UNESCAPED_UNICODE);
            Logger::getInstance()->error($error);
            self::setError($error);
            return '';
        }

        return $result['openid'];
    }

    public function list_contact_way(array $param)
    {

        $access_token = $this->get_access_token();

        if (!$access_token) {
            return false;
        }

        $res = Help::curl('post', 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list_contact_way?access_token=' . $access_token, json_encode($param));

        if ($res['response_code'] !== 0) {
            $error = '获取企业已配置的「联系我」列表失败！MESSAGE1：' . $res['response_message'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '获取企业已配置的「联系我」列表失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $this->setSuccess($result);

        return true;

    }

    public function del_contact_way(array $param, string $access_token)
    {


//        $access_token = $this->get_access_token(');
//
//        if (!$access_token) {
//            return false;
//        }

        $res = Help::curl('post', 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=' . $access_token, json_encode($param));

        if ($res['response_code'] !== 0) {
            $error = '删除企业已配置的「联系我」方式失败！MESSAGE1：' . $res['response_message'] . ', PARAM:' . json_encode($param);
            // Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '删除企业已配置的「联系我」方式失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', PARAM:' . json_encode($param);
            // Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $this->setSuccess($result);

        return true;

    }


    public function del_material(array $param, string $access_token)
    {


//        $access_token = $this->get_access_token(');
//
//        if (!$access_token) {
//            return false;
//        }

        $res = Help::curl('post', 'https://api.weixin.qq.com/cgi-bin/material/del_material?access_token=' . $access_token, json_encode($param));

        if ($res['response_code'] !== 0) {
            $error = '删除公众号素材失败！MESSAGE1：' . $res['response_message'] . ', PARAM:' . json_encode($param);
            // Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '删除公众号素材失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', PARAM:' . json_encode($param);
            // Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $this->setSuccess($result);

        return true;

    }


    /**
     * 手机号获取userid
     */
    public function get_userid(array $param): bool
    {

        $access_token = $this->get_access_token();

        if (!$access_token) {
            return false;
        }

        $res = Help::curl('post', 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token=' . $access_token, json_encode($param));

        if ($res['response_code'] !== 0) {
            $error = '手机号获取userid失败！MESSAGE1：' . $res['response_message'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '手机号获取userid失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $this->setSuccess($result);

        return true;

    }

    /**
     * 读取成员
     */
    public function get_user(array $param): bool
    {

        $access_token = $this->get_access_token();

        if (!$access_token) {
            return false;
        }

        $param['access_token'] = $access_token;

        $res = Help::curl('get', 'https://qyapi.weixin.qq.com/cgi-bin/user/get', $param);

        if ($res['response_code'] !== 0) {
            $error = '读取成员失败！MESSAGE1：' . $res['response_message'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '读取成员失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $this->setSuccess($result);

        return true;

    }

    /**
     * 更新成员
     * @param array $param
     * @return bool
     */
    public function update_user(array $param): bool
    {

        $access_token = $this->get_access_token();

        if (!$access_token) {
            return false;
        }

        $res = Help::curl('post', 'https://qyapi.weixin.qq.com/cgi-bin/user/update?access_token=' . $access_token, json_encode($param));

        if ($res['response_code'] !== 0) {
            $error = '更新成员失败！MESSAGE1：' . $res['response_message'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '更新成员失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $this->setSuccess($result);

        return true;

    }


    /**
     * 获取成员多次收消息详情
     * https://developer.work.weixin.qq.com/document/path/100133
     */
    public function get_chat_info(array $param): bool
    {

        $access_token = $this->get_access_token();

        if (!$access_token) {
            return false;
        }

        $res = Help::curl('post', 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/get_chat_info?access_token=' . $access_token, json_encode($param));

        if ($res['response_code'] !== 0) {
            $error = '获取成员多次收消息详情失败！MESSAGE1：' . $res['response_message'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $result = $res['response_content'];

        if ($result['errcode'] !== 0) {
            $error = '获取成员多次收消息详情失败！MESSAGE2：' . $result['errmsg'] . ', CODE:' . $result['errcode'] . ', PARAM:' . json_encode($param);
            Logger::getInstance()->error($error);
            self::setError($error);
            return false;
        }

        $this->setSuccess($result);

        return true;


    }


}